package nacos

import (
	"encoding/json"
	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"
	"go.uber.org/zap"
	"hosptial-record/config"
	"hosptial-record/global"
	"time"
)

type RegistryClient interface {
	RegisterServer(RegisterServerConfig) error
	RegisterConfig(RegisterConfConfig) error
	GetAgent(namespaceID string) ([]constant.ServerConfig, constant.ClientConfig)
}

func NewRegistry(config RegisterConfig) RegistryClient {
	return Registry{
		Host:     config.Host,
		Port:     config.Port,
		UserName: config.UserName,
		Password: config.Password,
	}
}

type RegisterConfig struct {
	Host     string
	Port     int
	UserName string
	Password string
}

type RegisterServerConfig struct {
	Host        string
	Port        int
	Name        string
	NamespaceID string
}

type RegisterConfConfig struct {
	Group       string
	ConfigName  string
	NamespaceID string
}

type Registry struct {
	Host     string
	Port     int
	UserName string
	Password string
}

func (r Registry) GetAgent(namespaceID string) ([]constant.ServerConfig, constant.ClientConfig) {
	ss := []constant.ServerConfig{
		{
			IpAddr: r.Host,
			Port:   uint64(r.Port),
		},
	}

	cc := constant.ClientConfig{
		NamespaceId: namespaceID,
		TimeoutMs:   uint64(time.Second * 5),
		LogLevel:    "debug",
		Username:    r.UserName,
		Password:    r.Password,
	}
	return ss, cc
}

func (r Registry) RegisterServer(config RegisterServerConfig) error {
	ss, cc := r.GetAgent(config.NamespaceID)
	client, err := clients.NewNamingClient(vo.NacosClientParam{
		ClientConfig:  &cc,
		ServerConfigs: ss,
	})
	if err != nil {
		zap.S().Errorf("注册服务中心失败：%s", err.Error())
		panic(err.Error())
	}
	// 定义服务实例信息
	instance := vo.RegisterInstanceParam{
		ServiceName: config.Name,
		Ip:          config.Host,
		Port:        uint64(config.Port),
		Weight:      10,
		Enable:      true,
		Healthy:     true,
		Ephemeral:   true,
	}
	// 注册实例
	if success, err := client.RegisterInstance(instance); success {
		zap.S().Info("服务注册成功")
		return nil
	} else {
		zap.S().Errorf("服务注册失败:%s", err.Error())
		return err
	}
}

func (r Registry) RegisterConfig(config RegisterConfConfig) error {
	// 获取配置信息
	ss, cc := r.GetAgent(config.NamespaceID)
	client, err := clients.NewConfigClient(vo.NacosClientParam{
		ServerConfigs: ss,
		ClientConfig:  &cc,
	})
	if err != nil {
		zap.S().Errorf("注册配置中心失败：%s", err.Error())
		panic(err)
	}

	//debug := GetEnvInfo("DEBUG")
	c := vo.ConfigParam{
		Group:  config.Group,
		DataId: config.ConfigName,
		OnChange: func(namespace, group, dataId, data string) {
			zap.S().Infof("配置数据发生变化：%s", data)
		},
	}
	// 获取文件信息
	var content string
	content, err = client.GetConfig(c)
	if err != nil {
		zap.S().Errorf("获取配置失败：%s", err.Error())
		panic(err)
	}
	// json转配置
	global.ServerConfig, err = Json2Config(content)
	if err != nil {
		zap.S().Errorf("配置解析失败：%s", err.Error())
		panic(err)
	}
	zap.S().Infof("配置信息：%s", content)
	// 监听文件变化
	err = client.ListenConfig(c)
	if err != nil {
		zap.S().Errorf("获取配置失败：%s", err.Error())
		panic(err)
	}
	return nil
}

// Json2Config json转配置
func Json2Config(content string) (*config.ServerConfig, error) {
	var conf config.ServerConfig
	// 编码
	if err := json.Unmarshal([]byte(content), &conf); err != nil {
		return nil, err
	}
	return &conf, nil
}
